package com.hibernate.rcache;

import com.hibernate.rcache.region.*;
import com.rcache.core.cache.Rcache;
import com.rcache.core.cache.strategy.FIFOCache;
import com.rcache.core.exception.ConfigurationException;
import com.rcache.core.manager.CacheManager;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.RegionFactory;
import org.hibernate.cache.internal.Timestamper;
import org.hibernate.cache.spi.*;
import org.hibernate.cache.spi.access.AccessType;
import org.hibernate.cfg.Settings;

import java.util.Properties;

public class RcacheRegionFactory implements RegionFactory {
    CacheManager cacheManager;
    private Settings settings;

    public void start(Settings settings, Properties properties) throws CacheException {
        try {
            this.settings = settings;
            cacheManager=CacheManager.newInstance();
            FIFOCache<String, Object> cache = new FIFOCache<String, Object>();
            cache.setCacheName("hibernate4");
            cacheManager.addCache(cache);
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }
    }

    public void stop() {
        if(cacheManager!=null){
            cacheManager=null;
        }
    }

    public boolean isMinimalPutsEnabledByDefault() {
        return false;
    }

    public AccessType getDefaultAccessType() {
        return null;
    }


    public long nextTimestamp() {
        return Timestamper.next();
    }



    public NaturalIdRegion buildNaturalIdRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
        return new RcacheNaturalIdRegion(cacheManager,getCache(regionName),properties,settings,metadata);
    }

    public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
        return new RcacheCollectionRegion(cacheManager,getCache(regionName),properties,settings,metadata);
    }

    public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException {
        System.out.println("EntityRegion:"+regionName);
        return new RcacheEntityRegion(cacheManager,getCache(regionName),properties,settings,metadata);
    }


    public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
        System.out.println("QueryResultsRegion:"+regionName);
        return new RcacheQueryResultsRegion(cacheManager,getCache(regionName),settings,properties);

    }



    public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
        System.out.println("TimestampsRegion:"+regionName);
        return new RcacheTimestampsRegion(cacheManager,getCache(regionName),properties);
    }

    private Rcache getCache(String regionName) {
        Rcache cache = cacheManager.getCache(regionName);
        if(cache==null){
            Rcache rcache=new FIFOCache();
            rcache.setCacheName(regionName);
            cacheManager.addCache(rcache);
            return rcache;
        }else {
            return cache;
        }
    }
}
